package com.chuhe.starry.service.impl;

import com.chuhe.common.constans.MyConstants;
import com.chuhe.common.domain.dto.MessageSendDto;
import com.chuhe.common.domain.dto.TokenUserInfoDto;
import com.chuhe.common.domain.entity.GroupInfo;
import com.chuhe.common.domain.entity.UserContact;
import com.chuhe.common.domain.entity.UserContactApply;
import com.chuhe.common.domain.entity.UserInfo;
import com.chuhe.common.domain.enums.*;
import com.chuhe.common.domain.query.PaginationResultVO;
import com.chuhe.common.domain.vo.req.ApplyAddReq;
import com.chuhe.common.domain.vo.req.DealApplyReq;
import com.chuhe.common.domain.vo.resp.ApiResult;
import com.chuhe.common.domain.vo.resp.LoadApplyResp;
import com.chuhe.common.exception.BusinessException;
import com.chuhe.common.exception.CommonErrorEnum;
import com.chuhe.common.utils.AssertUtil;
import com.chuhe.starry.dao.GroupInfoDao;
import com.chuhe.starry.dao.UserContactApplyDao;
import com.chuhe.starry.dao.UserContactDao;
import com.chuhe.starry.dao.UserInfoDao;
import com.chuhe.starry.service.UserContactApplyService;
import com.chuhe.starry.service.UserContactService;
import com.chuhe.starry.service.adapter.UserContactAdapter;
import com.chuhe.starry.service.adapter.UserContactApplyAdapter;
import com.chuhe.starry.websocket.MessageHandler;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

/**
 * @Author: 楚河
 * @Date: 2025年05月16日16:10
 */
@Service
public class UserContactApplyServiceImpl implements UserContactApplyService{
    @Autowired
    private UserContactDao userContactDao;
    @Autowired
    private GroupInfoDao groupInfoDao;
    @Autowired
    private UserInfoDao userInfoDao;
    @Autowired
    private UserContactApplyDao userContactApplyDao;
    @Autowired
    private UserContactService userContactService;
    @Autowired
    private MessageHandler messageHandler;

    /**
     * 添加联系人
     * @Author: 楚河
     * @Date: 2025-05-16 15:58
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer applyAdd(TokenUserInfoDto userInfo, ApplyAddReq req) {
        //查看要添加的联系人类型
        UserContactTypeEnum typeEnum = UserContactTypeEnum.getByName(req.getContactType());
        AssertUtil.isEmpty(typeEnum, CommonErrorEnum.CODE_600);
        //默认申请信息
        if (StringUtils.isEmpty(req.getApplyInfo())) {
            req.setApplyInfo(String.format(MyConstants.APPLY_INFO_TEMPLATE, userInfo.getNickName()));
        }
        //获取当前时间
        long curDate = System.currentTimeMillis();
        Integer joinType = null; //可加入类型  0:直接加入 1：需要审核
        String receiveUserId = req.getContactId();
        //添加类型
        if(UserContactTypeEnum.GROUP == typeEnum){
            //群聊
            GroupInfo groupInfo = groupInfoDao.selectByGroupId(req.getContactId());
            if(Objects.isNull(groupInfo) || GroupStatusEnum.DISSOLUTION.getStatus().equals(groupInfo.getStatus())){
                throw new BusinessException("群聊不存在或已被解散，无法加入");
            }
            receiveUserId = groupInfo.getGroupOwnerId();
            joinType = groupInfo.getJoinType();
        }else {
            //好友
            //对方是否真实存在
            UserInfo user = userInfoDao.selectByUserId(req.getContactId());
            AssertUtil.isEmpty(user,"用户不存在");
            //查询是否已经是好友，如果已经拉黑或被拉黑则无法添加
            UserContact userContact = userContactDao.selectByUserIdAndContactId(userInfo.getUserId(),req.getContactId());
            if(Objects.nonNull(userContact)
                    && (UserContactStatusEnum.BLACKLIST.getStatus().equals(userContact.getStatus())
                    || UserContactStatusEnum.BLACKLIST_BE.getStatus().equals(userContact.getStatus()))){
                throw new BusinessException("对方或你已经被拉黑，无法添加");
            }
            joinType = user.getJoinType();
        }
        //直接加入不用记录申请记录
        if(JoinTypeEnum.JOIN.getType().equals(joinType)){
            userContactService.addUserContact(userInfo.getUserId(),req.getContactId(),req.getApplyInfo(),receiveUserId,typeEnum.getType());
            return joinType;
        }
        UserContactApply dbApply = userContactApplyDao.selectByApplyUserIdAndReceiveUserIdAndContactId(userInfo.getUserId(),receiveUserId,req.getContactId());
        if(Objects.isNull(dbApply)){
            //申请记录入库
            UserContactApply userContactApply = UserContactApplyAdapter.buildAddUserContactApply(userInfo.getUserId(),typeEnum.getType(),receiveUserId,curDate,req.getContactId(), UserContactApplyStatusEnum.INIT.ordinal(),req.getApplyInfo());
            userContactApplyDao.save(userContactApply);
        }else {
            //更新记录入库
            UserContactApply userContactApply = UserContactApplyAdapter.buildEditUserContactApply(UserContactApplyStatusEnum.INIT.getStatus(),curDate,req.getApplyInfo());
            userContactApplyDao.updateContactApply(userContactApply,dbApply.getApplyId());
        }
        // ws添加联系人发送消息
        if (dbApply == null || !UserContactApplyStatusEnum.INIT.getStatus().equals(dbApply.getStatus())) {
            //如果是待处理状态就不发消息，避免重复发送
            //发送ws消息
            MessageSendDto messageSend = new MessageSendDto();
            messageSend.setMessageType(MessageTypeEnum.CONTACT_APPLY.getType());
            messageSend.setMessageContent(req.getApplyInfo());
            messageSend.setContactId(receiveUserId);
            messageHandler.sendMessage(messageSend);
        }
        return joinType;//0：直接返回添加成功 1：已发出好友申请
    }

    /**
     * 加载申请列表
     * @Author: 楚河
     * @Date: 2025-05-16 18:43
     */
    @Override
    public PaginationResultVO<LoadApplyResp> loadApplyByPage(String userId, Integer pageNo) {
        LoadApplyResp userContactApply = UserContactApplyAdapter.buildLoadApply(userId,pageNo);
        return userContactApplyDao.findApplyListByPage(userContactApply);
    }

    /**
     * 处理申请
     * @Author: 楚河
     * @Date: 2025-05-16 20:10
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object dealWithApply(String userId, DealApplyReq req) {
        //提交的处理状态异常
        UserContactApplyStatusEnum statusEnum = UserContactApplyStatusEnum.getByStatus(req.getStatus());
        AssertUtil.isTrue((Objects.isNull(statusEnum) || UserContactApplyStatusEnum.INIT == statusEnum),CommonErrorEnum.CODE_600);
        //用户不存在 非处理人
        UserContactApply applyInfo = userContactApplyDao.selectByApplyId(req.getApplyId());
        AssertUtil.isTrue((Objects.isNull(applyInfo) || !userId.equals(applyInfo.getReceiveUserId())),CommonErrorEnum.CODE_600);

        //更新申请信息 只能由待处理更新为其他状态
        Integer count = userContactApplyDao.selecyInitCount(req.getApplyId(),UserContactApplyStatusEnum.INIT.getStatus());
        AssertUtil.isTrue(count == 0,CommonErrorEnum.CODE_600);

        //更新记录表显示状态
        UserContactApply userContactApply = UserContactApplyAdapter.buildUpdateApply(req);
        userContactApplyDao.updateApplyInfo(userContactApply);

        //处理为 添加联系人
        if(UserContactApplyStatusEnum.PASS.getStatus().equals(req.getStatus())){
            userContactService.addUserContact(applyInfo.getApplyUserId(),applyInfo.getContactId(),applyInfo.getApplyInfo(),applyInfo.getReceiveUserId(),applyInfo.getContactType());
            return null;
        }

        //处理为 申请人被接收人首次单方面拉黑
        if(UserContactApplyStatusEnum.BLACKLIST == statusEnum){
            UserContact userContact = UserContactAdapter.buildBlackContact(applyInfo);
            userContactDao.save(userContact);
        }
        return null;
    }
}
